namespace designpatternsplusplus.decorator.DomainEntities
{
    #region

    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using designpatternsplus.contracts;

    #endregion

    /// <summary>
    /// Our store has a tight audit history which is seperate from the
    /// receipts we hand to the customer. We have a strictly controller 'Queue'
    /// where receipts are persisted for accounting and tax concerns .
    /// For example soon after we release this app we are audited and must
    /// prove we had complied with all of the rules as given. For every transaction 
    /// we must provide a 'snapshot' which is why you notice we store the serialized
    /// instance, not a reference. We must have point in time (I know not asked for
    /// but common)
    /// 
    /// 
    /// Single Responsibility : Highest Level Entry Point
    /// which dispatches to other services for base store 
    /// operations such as execute sale.
    /// 
    /// </summary>
    public sealed class ShoppingCartSection : KeyedCollection<char, ShoppingCartAisle>,
                                              IMarketLayoutSection
    {
        ShoppingCartSection(int aisles)
        {
            var row_start = 'A';

            for (var i = 0; i < aisles; i++)
            {
                var item = new ShoppingCartAisle(OneStackOfShoppingCarts)
                           {
                               RowLetter = row_start
                           };

                row_start += row_start;

                Add(item);
            }
        }

        /// <summary>
        /// Gets the carts from storage.We just
        /// opened and corporate gave us 100 shiny new
        /// carts
        /// </summary>
        /// <returns></returns>
        ShoppingCartAisle OneStackOfShoppingCarts
        {
            get
            {
                return new ShoppingCartAisle
                    (Enumerable.Range(0, 100).Select
                         (x => ShoppingCart.Prepare(Guid.NewGuid())));
            }
        }

        /// <summary>
        /// Setups this instance.
        /// </summary>
        /// <returns></returns>
        public static ShoppingCartSection Setup(int numberOfRows)
        {
            return new ShoppingCartSection(numberOfRows);
        }

        #region Overrides of KeyedCollection<int,ShoppingCartAisle>

        /// <summary>
        /// When implemented in a derived class, extracts the key from the specified element.
        /// </summary>
        /// <returns>
        /// The key for the specified element.
        /// </returns>
        /// <param name="item">The element from which to extract the key.</param>
        protected override char GetKeyForItem(ShoppingCartAisle item)
        {
            return item.RowLetter;
        }

        #endregion
    }
}